package com.maimao.auth.mobilecCode;

import com.maimao.auth.model.SysAuthUser;
import com.maimao.auth.service.BaseUserDetailsService;
import com.maimao.auth.utils.WebUtils;
import com.maimao.core.constant.RedisKeys;
import com.maimao.core.constant.SessionKey;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;

import javax.servlet.http.HttpSession;

/**
 * 手机验证码验证Provider
 *
 * @author MaoLin Wang
 * @date 2020/12/13 8:29 下午
 */
public class MobileCodeAuthenticationProvider implements AuthenticationProvider {
    private BaseUserDetailsService baseUserDetailsService;
    private RedisTemplate redisTemplate;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        MobileCodeAuthenticationToken mobileCodeAuthenticationToken = (MobileCodeAuthenticationToken) authentication;
        SysAuthUser authUser = (SysAuthUser) baseUserDetailsService.loadUserByMobile((String) mobileCodeAuthenticationToken.getPrincipal());

        if (authUser == null) {
            throw new UsernameNotFoundException("手机号未注册");
        }
        String mobile = (String) mobileCodeAuthenticationToken.getPrincipal();
        String cachedCode = getCacheCode(mobile);

        String inputCode = mobileCodeAuthenticationToken.getCode();
        if (StringUtils.isEmpty(cachedCode) || !inputCode.equals(cachedCode)) {
            throw new InvalidGrantException("验证码错误");
        } else {
            removeCode(mobile);
        }
        //这时候已经认证成功了
        MobileCodeAuthenticationToken authenticationResult = new MobileCodeAuthenticationToken(authUser, authUser.getAuthorities());
        authenticationResult.setDetails(mobileCodeAuthenticationToken.getDetails());

        return authenticationResult;
    }

    private void removeCode(String username) {
        redisTemplate.delete(RedisKeys.LOGIN_MOBILE_PREFIX + username);
    }

    private String getCacheCode(String username) {
        String code = "";
        try {
            code = (String) redisTemplate.opsForValue().get(RedisKeys.LOGIN_MOBILE_PREFIX + username);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return code;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return MobileCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public void setBaseUserDetailsService(BaseUserDetailsService baseUserDetailsService) {
        this.baseUserDetailsService = baseUserDetailsService;
    }

    public void setRedisTemplate(RedisTemplate jsonRedisTemplate) {
        this.redisTemplate = jsonRedisTemplate;
    }
}
